"""领域数据模型定义。

通过数据类抽象 JSON 文件中的分类、设备与属性结构，便于后续在界面层和服务层中复用。
"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any, Dict, List, Optional


@dataclass(slots=True)
class TypeNode:
    """设备分类节点，支持父子级组织。"""

    id: int
    name: str
    parent_id: Optional[int]
    product_key: Optional[str] = None
    sort_number: Optional[int] = None
    children: List["TypeNode"] = field(default_factory=list)

    def add_child(self, child: "TypeNode") -> None:
        self.children.append(child)

    def sort_key(self) -> int:
        """提供可配置的排序权重，默认返回 0。"""
        if self.sort_number is None:
            return 0
        try:
            return int(self.sort_number)
        except (TypeError, ValueError):
            return 0


@dataclass(slots=True)
class DeviceAttribute:
    """设备属性（IOM），用于生成测试表单。"""

    id: int
    nickname: str
    resource_name: str
    point_type: str
    value_type: str
    read_write: str
    units: Optional[str]
    description: Optional[str]
    default_value: Optional[str] = None
    optional_values: Dict[str, str] = field(default_factory=dict)

    def to_form_label(self) -> str:
        extra = f"（{self.units}）" if self.units else ""
        return f"{self.nickname}{extra}"


@dataclass(slots=True)
class Device:
    """IoT 设备模型，包含基本信息和属性集合。"""

    id: int
    nickname: str
    device_name: str
    product_key: str
    device_sn: str
    device_secret: str
    type_node_id: int
    type_node_name: str
    type_node_parent_id: Optional[int]
    attributes: List[DeviceAttribute] = field(default_factory=list)
    raw_payload: Dict[str, Any] = field(default_factory=dict)

    def topic(self, template: str | None = None) -> str:
        """生成设备属性上报所需的 MQTT topic。
        
        Args:
            template: Topic模板，如果为None则使用默认模板
        """
        if template is None:
            # 默认模板（向后兼容）
            return f"v1/{self.product_key}/{self.device_sn}/sys/property/up"
        return template.format(product_key=self.product_key, device_sn=self.device_sn)

    def summary(self) -> Dict[str, Any]:
        """整理设备基本信息，供界面展示或调试。"""
        return {
            "nickname": self.nickname,
            "type_name": self.type_node_name,
            "product_key": self.product_key,
            "device_sn": self.device_sn,
            "device_secret": self.device_secret,
            "topic": self.topic(),
        }


